package com.myx.javase.reflex;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Date;

/**
 * 描述:反射演示类
 * @author: myx
 * @date: 2018/11/27
 * Copyright © 2018-hotpot. All rights reserved.
 */
public class TestReflex {

    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchFieldException, NoSuchMethodException, InvocationTargetException {
        //1.初始化的操作 无参数构造函数
        User user =new User();
        user.setName("myx");
        System.out.println(user.getName());
        System.out.println("---------------------------------------");
        //2.使用Java的反射机制创建对象 类的完整路径declaredMethods
        Class<?> userclass = Class.forName("com.myx.javase.reflex.User");
        //3.使用反射机制创建对象
        User user1 = (User) userclass.newInstance();
        user1.setName("反射获取");
        System.out.println(user1.getName());
        System.out.println("---------------------------------------");
        //4.反射应用场景 1.jdbc连接、springIOC底层使用反射机制+DOM4J 2、框架hibernate、mybatis使用到反射机制
        //5.使用反射机制 获取类的方法信息
        Method[] declaredMethods = userclass.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            System.out.println(declaredMethod.getName());
        }
        System.out.println("---------------------------------------");
        //6.获取类属性
        Field[] declaredFields = userclass.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            System.out.println(declaredField.getName());
        }
        System.out.println("---------------------------------------");
        //7.允许反射给私有变量赋值
        Field name = userclass.getDeclaredField("name");
        name.setAccessible(true);//这里直接修改权限即可
        name.set(user1,"反射设置权限直接修改私有属性");
        System.out.println(user1.getName());
        System.out.println("---------------------------------------");
        //8.调用有参构造函数
        Constructor<?> constructor = userclass.getConstructor(String.class, Integer.class, Date.class);
        User user2 = (User) constructor.newInstance("反射调用有参构造函数初始化对象", null, null);
        System.out.println(user2.getName());
        //9.禁用反射机制初始化(将构造函数私有化)

        //10.调用私有化构造函数初始化对象
        Constructor<?> constructor1 = userclass.getDeclaredConstructor(String.class, Integer.class, Date.class);
        constructor1.setAccessible(true);
        User user3 = (User) constructor1.newInstance("反射调用私有有参构造函数初始化对象", null, null);
        System.out.println(user3.getName());
    }
}
